package org.demo.base.file.service.impl;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.demo.base.file.domain.SysFile;
import org.demo.base.file.enums.FileType;
import org.demo.base.file.mapper.FileMapper;
import org.demo.base.file.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.UUID;

/**
 * @author tomdog
 */
@Service
@Slf4j// lombok简化了log代码
public class FIleServiceImpl implements FileService {

    private final String BASE_DIR = "D:/file";

    @Autowired
    private FileMapper fileMapper;

    /**
     * 上传文件
     */
    @Override
    public SysFile upload(MultipartFile file, String category) {
        log.info("=== 上传文件");// 日志常见级别 DEBUG、INFO、WARN、ERROR
        // 获取文件后缀名
        String ext = this.getFileExt(file.getOriginalFilename());
        // 生成随机文件名
        String fileName = UUID.randomUUID() + (ext==null?"":"."+ext);
        // 以随机文件名保存
        String filePath = "/" + fileName;
        String targetFile = BASE_DIR + filePath;
        try(
                InputStream inputStream = file.getInputStream();
                FileOutputStream out = new FileOutputStream(targetFile)
        ) {
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buffer))>0) {
                out.write(buffer, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 拼文件对象，保存到数据库
        SysFile build = SysFile.builder()
                .type(this.readFileType(file.getOriginalFilename()).name())// 通过后缀名自动识别：图片（在线预览）、普通文件不能预览
                .fileName(fileName)// 随机文件名
                .oirginalName(file.getOriginalFilename())// 原始文件名
                .category(category)
                .path(filePath)// 存储路径
                .build();
        // 保存对象
        fileMapper.insert(build);
        return build;
    }

    /**
     * 获取文件后缀名
     * @return
     */
    public String getFileExt(String fileName) {
        // 获取文件后缀
        String[] split = fileName.split("\\.");
        if(split.length<2) {
            return null;// 没有类型
        }else {
            return split[split.length - 1];
        }
    }

    /**
     * 根据文件名读取文件类型
     */
    public FileType readFileType(String fileName) {
        if(fileName==null) {
            return FileType.NORMAL;
        }
        // 获取文件后缀
        String sub = this.getFileExt(fileName);
        if(sub==null) {
            return FileType.NORMAL;
        }
        // 根据文件后缀返回不同的枚举
        switch (sub) {// 常见的图片后缀识别出来
            case "jpg":
            case "png":
            case "gif":
            case "jpeg":
            case "JPG":
            case "PNG":
            case "GIF":
            case "JPEG": return FileType.IMG;
            default: return FileType.NORMAL;
        }
    }

    @Override
    public String readFileName(String path) {
        // hello/1\xxx.txt
        if(path==null) {
            return "";
        }
        // 获取路径中的文件名
        path = path.replaceAll("\\\\", "/");
        String[] split = path.split("/");
        return split[split.length - 1];
    }

    /**
     * 下载文件
     * 获取这个文件的输入流，不需要考虑流是什么样的文件
     */
    @SneakyThrows
    @Override
    public FileInputStream download(String path) {
        // 拼接文件路径
        String targetFile = BASE_DIR + "/" + path;
        return new FileInputStream(targetFile);
    }

    /**
     * 根据id获取文件信息
     */
    @Override
    public SysFile getFileInfoById(Long id) {
        return null;
    }
}
